home *** CD-ROM | disk | FTP | other *** search
- TITLE scrn3.asm
-
- ; AUTHOR Tim Spencer - Compuserve [73657,1400]
- ; DATE March 17, 1987
-
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
- _TEXT ENDS
-
- _DATA SEGMENT WORD PUBLIC 'DATA'
- SCRN STRUC ; screen data structure - defined in video.h
- off dw 0 ; offset (cursor position)
- seg dw 0 ; screen buffer address
- port dw 0 ; status port address
- attrib dw 0 ; attribute to use
- cgacrd dw 0 ; enable retrace checking if not zero
- SCRN ENDS
-
- _DATA ENDS
-
- DGROUP GROUP _DATA
- ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING
-
-
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
-
- ;-----------------------------------------------------------------------;
- ; scrn_restore - MSC callable function to restore a rectangular area ;
- ; of the screen buffer. Checks for vertical retrace ;
- ; only if the external structure member cga_card is ;
- ; non-zero. &scrn is the address of that structure. ;
- ; (see video.h). ;
- ; ; ;
- ; Note: This procedure uses stosb in retrace checking mode (instead of ;
- ; movsb) because it stuffs the char/attrib into the screen buffer ;
- ; slightly faster. ;
- ; ;
- ; Usage: scrn_restore(left, right, top, bottom, data_buff, &scrn) ;
- ; ;
- ;-----------------------------------------------------------------------;
- _DATA SEGMENT
- restore_args STRUC ; structure for easy argument reference
- dw 0 ; saved BP value
- dw 0 ; return address
- rleft dw 0 ; rectangular boundries...
- rright dw 0
- rtop dw 0
- rbottom dw 0
- mdata dw 0 ; address of data buffer to write to screen
- mstruct dw 0 ; pointer to SCRN structure(defined in video.h)
- restore_args ENDS
-
- cga db 0 ; variable to hold cga_card value
- _DATA ENDS
-
- PUBLIC _scrn_restore
-
- _scrn_restore PROC NEAR
- push bp ; set up frame pointer
- mov bp,sp
- push si
- push di
- mov bx,[bp].mstruct ; get pointer to SCRN structure
- les di,dword ptr[bx].off ; get scrn seg in es, off in di
- mov dx,[bx].port ; get status port address
- mov ax,[bx].cgacrd ; hold cga status in variable cga
- mov cga,al
- mov si,[bp].mdata ; make si point to data buffer
- mov bh,byte ptr[bp].rtop ; top will be incremented until it
- mov bl,byte ptr[bp].rbottom ; is greater than bottom, then exit.
- xor cx,cx ; set initial logical cursor position
- mov cl,bh ; by getting top into cx,
- mov al,80 ; multiplying by 80,
- mul cl
- mov cx,ax
- add cx,[bp].rleft ; adding left.
- shl cx,1 ; and multiplying by 2
- mov di,cx ; put result into di
- mov cx,[bp].rright ; get the length of one line into
- sub cx,[bp].rleft ; cx by subtracting left from right
- add cx,1 ; adding 1
- push cx ; save it
- mov ax,79 ; calculate offset from end of line to
- sub ax,[bp].rright ; the start of the next line
- add ax,[bp].rleft
- shl ax,1
- push ax ; and save it
- write_line:
- cmp cga,0 ; cga card in use?
- jnz rwait1 ; yes, go wait
- rep movsw ; no, warp speed.
- jmp short rcheck_pos ; go check position
- rwait1:
- in al, dx ; wait for end of retrace
- shr al, 1 ; test horizontal trace bit
- jc rwait1 ; loop if still tracing
- cli ; disable writus interuptus
- rwait2:
- in al, dx ; now wait until the very moment
- shr al, 1 ; when the next retrace begins
- jnc rwait2 ; still waiting...
- mov al,[si] ; load the char into al for stosb
- stosb ; write it and update pointer
- sti ; enable interrupts again
- inc si ; point si at attribute
- rwait3:
- in al, dx ; repeat these steps for the attribute
- shr al, 1
- jc rwait3
- cli
- rwait4:
- in al, dx
- shr al, 1
- jnc rwait4
- mov al,[si] ; load the attribute
- stosb
- sti
- inc si ; point si at next char
- loop rwait1
- rcheck_pos:
- pop ax ; restore offset to next line start
- pop cx ; restore count
- inc bh ; is top greater than bottom yet?
- cmp bh,bl
- ja rexit ; yes.
- push cx ; no, save count again
- push ax ; save line start offset again
- add di,ax ; move di to start of next line
- jmp short write_line ; write another line
- rexit:
- pop di
- pop si
- pop bp
- ret
- _scrn_restore ENDP
-
-
-
- ;-----------------------------------------------------------------------;
- ; scrn_save - MSC callable function to save a rectangular area of the ;
- ; screen to a user defined buffer. ;
- ; ;
- ; Usage: scrn_save(left, right, top, bottom, data_buff, &scrn) ;
- ;-----------------------------------------------------------------------;
- _DATA SEGMENT
- save_args STRUC ; structure for easy argument reference
- dw 0 ; saved bp value
- dw 0 ; return address
- sleft dw 0 ; rectangular boundries
- sright dw 0
- stop dw 0
- sbottom dw 0
- sbuff dw 0 ; user defined buffer to hold screen contents
- sstruct dw 0 ; pointer to SCRN structure (see video.h)
- save_args ENDS
- _DATA ENDS
-
- scga db 0 ; store cga true/false value here - must be
- ; declared outside data segment because es and
- ; ds are swapped in this function.
-
- PUBLIC _scrn_save
-
- _scrn_save PROC NEAR
- push bp ; set up frame pointer
- mov bp,sp
- push si
- push di
- push ds
- mov bx,[bp].mstruct ; get pointer to SCRN structure
- mov dx,[bx].port ; get status port address
- mov ax,[bx].cgacrd ; hold cga status in variable scga
- mov scga,al
- mov ax,ds
- mov es,ax ; get data segment into es
- mov di,[bp].sbuff ; and offset of user buffer in di
- mov ax,[bx].seg ; get the screen segment and
- mov ds,ax ; put in ds
- mov bh,byte ptr[bp].stop ; top will be incremented until it
- mov bl,byte ptr[bp].sbottom ; is greater than bottom, then exit.
- xor cx,cx ; set initial logical cursor position
- mov cl,bh ; by getting top into cx,
- mov al,80 ; multiplying by 80,
- mul cl
- mov cx,ax
- add cx,[bp].sleft ; adding left.
- shl cx,1 ; and multiplying by 2
- mov si,cx ; put result into si
- mov cx,[bp].sright ; get the length of one line into
- sub cx,[bp].sleft ; cx by subtracting left from right
- add cx,1 ; adding 1
- push cx ; save it
- mov ax,79 ; calculate offset from end of line to
- sub ax,[bp].sright ; the start of the next line
- add ax,[bp].sleft
- shl ax,1
- push ax ; and save it
- read_line:
- cmp cga,0 ; cga card in use?
- jnz swait1 ; yes, go wait
- rep movsw ; no, warp speed.
- jmp short scheck_pos ; go check position
- swait1:
- in al, dx ; wait for end of retrace
- shr al, 1 ; test horizontal trace bit
- jc swait1 ; loop if still tracing
- cli ; disable writus interuptus
- swait2:
- in al, dx ; now wait until the very moment
- shr al, 1 ; when the next retrace begins
- jnc swait2 ; still waiting...
- mov al,[si] ; load the char into al for stosb
- stosb ; write it and update pointer
- sti ; enable interrupts again
- inc si ; point si at attribute
- swait3:
- in al, dx ; repeat these steps for the attribute
- shr al, 1
- jc swait3
- cli
- swait4:
- in al, dx
- shr al, 1
- jnc swait4
- mov al,[si] ; load the attribute
- stosb
- sti
- inc si ; point si at next char
- loop swait1
- scheck_pos:
- pop ax ; restore offset to next line start
- pop cx ; restore count
- inc bh ; is top greater than bottom yet?
- cmp bh,bl
- ja sexit ; yes.
- push cx ; no, save count again
- push ax ; save line start offset again
- add si,ax ; move di to start of next line
- jmp short read_line ; write another line
- sexit:
- pop ds
- pop di
- pop si
- pop bp
- ret
- _scrn_save ENDP
-
-
- _TEXT ENDS
-
- END